/*	This file is part of AstroAttack.
*
*	AstroAttack is free software; you can redistribute it and/or modify
*	it under the terms of the GNU General Public License as published by
*	the Free Software Foundation; either version 2 of the License, or
*	(at your option) any later version.
*	
*	AstroAttack is distributed in the hope that it will be useful,
*	but WITHOUT ANY WARRANTY; without even the implied warranty of
*	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*	GNU General Public License for more details.
*	
*	You should have received a copy of the GNU General Public License
*	along with AstroAttack; if not, write to the Free Software
*	Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*	
*	$Id: ImageCache.java 66 2007-01-06 05:45:31Z xdracox $
*/

/**	The AstroAttack package contains all the classes that belong to the
*	AstroAttack program.
*/
package AstroAttack;

import java.awt.Image;
import java.awt.Toolkit;
import java.awt.MediaTracker;
import java.awt.Canvas;
import java.awt.image.BufferedImage;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsEnvironment;
import java.awt.Transparency;

import java.util.Map;
import java.util.TreeMap;
import java.util.Collection;

import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;

import java.net.URL;

/**	The ImageCache class loads images and keeps them in a cache. It uses
*	a TreeMap to keep a relationship between the image and it's location.
*/
public class ImageCache
{
	/**	The single instance of the ImageCache class. */
	private static ImageCache m_ref = null;
	
	/**	Since the ImageCache class is a singleton, this method is used to
	*	retrieve or create the instance of it.
	*	@param	p_imgPath	path to where the image files are located
	*	@param	comp		the Component to use for the MediaTracker
	*	@return	
	*/
	public static ImageCache getCache(String p_imgPath, Canvas canvas)
	{
		if ( m_ref == null )
			m_ref = new ImageCache(p_imgPath, canvas);
		
		return m_ref;
	}
	
	/** This method returns the already initialized instance of the ImageCache
	*	or null if it has not been initialized.
	*	@return	the 
	*/
	public static ImageCache getCache()
	{
		return m_ref;
	}
	
	/** Map of all the loaded images. */
	private Map<String, Image> m_imgs;
	/** Location of all the image files. */
	private String m_imgPath;
	/**	ID for the last image added. */
	private int m_id = 0;
	/** Component. */
	private Canvas m_canvas;
	
	/**	Constructor initializes private members.
	*	@param	p_imgPath	path to where the image files are located
	*/
	private ImageCache(String p_imgPath, Canvas canvas)
	{
		setImgPath(p_imgPath);
		m_imgs = new TreeMap<String, Image>();
		m_canvas = canvas;
	}
	
	/**	Changed the location of the images.
	*	@param	p_imgPath	new location
	*/
	public void setImgPath(String p_imgPath)
	{
		Debug.println("Changing image path:");
		Debug.println("\told path: " + m_imgPath);
		
		if ( !p_imgPath.endsWith("/") )
			p_imgPath += "/";
		m_imgPath = p_imgPath;
		
		Debug.println("\tnew path: " + m_imgPath);
	}
	
	/** The loadAll() method adds all of the images that will be used to a map
	*	so that all classes can quickly access them later.
	*	@param	p_imgs	the files to load
	*   @return true if all images were loaded correctly
	*/
	public boolean loadAll(Collection<String> p_imgs)
	{
		Debug.println("Loading images:");
		
		boolean allOk = true;
		
		for ( String imgName : p_imgs )
		{
			BufferedImage srcImage = null;
			
			try
			{
				Debug.print("\tloading " + imgName + "... ");
				String fullPath = m_imgPath + imgName;
				
				URL url = new File(fullPath).toURI().toURL();
				
				if ( url != null )
				{
					srcImage = ImageIO.read(url);
					Debug.println("ok");
					
					GraphicsConfiguration gc = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration();
					Image img = gc.createCompatibleImage(srcImage.getWidth(), srcImage.getHeight(), Transparency.BITMASK);
					img.getGraphics().drawImage(srcImage, 0, 0, null);
					
					double w = m_canvas.getWidth() * img.getWidth(null) / AstroFrame.DEFAULT_WIDTH;
					double h = m_canvas.getHeight() * img.getHeight(null) / AstroFrame.DEFAULT_HEIGHT;
					
					Debug.println("\trescaling " + imgName);
					Debug.println("\tnew width: " + w);
					Debug.println("\tnew height: " + h);
					
					Image rescale = img.getScaledInstance((int)w, (int)h, Image.SCALE_DEFAULT);
					
					m_imgs.put(imgName, rescale);
				}
				else
					throw new Exception();
			}
			catch ( Exception e )
			{
				Debug.println("failed.");
				allOk = false;
			}
		}
		
		return allOk;
	}
	
	
	/** The getImage() retrieves an image that was previously loaded by this
	*	ImageCache
	*	@param	p_img	the file to load
	*	@return	the loaded image
	*/
	public Image getImage(String p_imgName)
	{
		Debug.println("Getting image: " + p_imgName);
		
		if(m_imgs.get(p_imgName) == null)
			Debug.println("\t" + p_imgName + " was not loaded.");
		
		return m_imgs.get(p_imgName);
	}
}
